package com.fjwt.gz.service.activity;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.fjwt.gz.components.oss.model.OssFileConfig;
import com.fjwt.gz.components.oss.service.OssFileService;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.db.entity.SysExportTaskEntity;
import com.fjwt.gz.db.vo.ExportAwardVO;
import com.opencsv.CSVWriter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.*;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAccessor;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

/**
 * 导出活动报表
 *
 */
@Slf4j
@Service
public abstract class AbstractExportReport<T> {

    @Autowired
    private OssFileService ossFileService;

    /**
     * 导出活动Excel报表
     **/
    public String exportActivityExcel(SysExportTaskEntity sysExportTaskEntity) {
        return "";
    }


    /**
     * 生成CSV并上传到OSS（优化版）
     * @param list 数据列表
     * @param headerAliasMap 表头映射（key:字段名, value:显示名）
     * @param sysExportTaskEntity 导出任务实体
     * @return OSS文件URL
     */
    protected String createExcelAndUploadOssUrl(List<T> list, Map<String, String> headerAliasMap, SysExportTaskEntity sysExportTaskEntity) {
        String successUrl = "";
        if (!list.isEmpty()) {
            String successFileName = String.format("./temp/ExportExcel/%s%s.csv", DateUtil.date().getTime(), sysExportTaskEntity.getFileName());
            File file = FileUtil.touch(successFileName);

            // 定义时间格式化器（线程安全）
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

            // 使用 OutputStreamWriter 指定 UTF-8 编码
            try (CSVWriter writer = new CSVWriter(
                    new java.io.OutputStreamWriter(
                            new java.io.FileOutputStream(file),
                            java.nio.charset.StandardCharsets.UTF_8),
                    ',',  // 分隔符
                    CSVWriter.DEFAULT_QUOTE_CHARACTER,
                    CSVWriter.DEFAULT_ESCAPE_CHARACTER,
                    CSVWriter.DEFAULT_LINE_END
            )) {
                // 写入表头
                writer.writeNext(headerAliasMap.values().toArray(new String[0]));

                // 写入数据
                for (T item : list) {
                    String[] row = headerAliasMap.keySet().stream()
                            .map(field -> {
                                Object value = BeanUtil.getProperty(item, field);
                                // 特殊处理时间类型字段
                                if (value instanceof TemporalAccessor) {  // 支持LocalDateTime/Date等
                                    return escapeCsvField(formatter.format((TemporalAccessor) value));
                                } else if (value instanceof Date) {
                                    return escapeCsvField(formatter.format(((Date) value).toInstant().atZone(ZoneId.systemDefault())));
                                }
                                return escapeCsvField(Convert.toStr(value, ""));
                            })
                            .toArray(String[]::new);
                    writer.writeNext(row);
                }
                // 关键：刷新缓冲区，确保数据写入磁盘
                writer.flush();
                // 现在获取文件大小是准确的
                sysExportTaskEntity.setFileSize(file.length());

                // 读取文件时也使用 UTF-8 编码
                org.springframework.mock.web.MockMultipartFile mockMultipartFile = new org.springframework.mock.web.MockMultipartFile(
                        successFileName,
                        successFileName,
                        "text/csv;charset=UTF-8",
                        new java.io.FileInputStream(file));
                successUrl = ossFileService.singleFileUpload(mockMultipartFile, OssFileConfig.BIZ_TYPE.DOWNLOAD);
            } catch (Exception e) {
                throw new BizException(e.getMessage());
            } finally {
                FileUtil.del(file);
            }
        }
        return successUrl;
    }
/**
 * 分页版（暂时不用）
 */
//    /**
//     * 分批生成CSV并上传到OSS（MyBatis-Plus分页版）
//     * @param dataProvider 数据提供者函数，接收(当前页, 每页数量)返回分页数据
//     * @param totalCount 总数据量
//     * @param headerAliasMap 表头映射（key:字段名, value:显示名）
//     * @param sysExportTaskEntity 导出任务实体
//     * @return OSS文件URL
//     */
//    protected String createExcelAndUploadOssUrlBatchMP(Function<long[], IPage<ExportAwardVO>> dataProvider,
//                                                       int totalCount,
//                                                       Map<String, String> headerAliasMap,
//                                                       SysExportTaskEntity sysExportTaskEntity) {
//        String successUrl = "";
//        if (totalCount > 0) {
//            String successFileName = String.format("./temp/ExportExcel/%s%s.csv", DateUtil.date().getTime(), sysExportTaskEntity.getFileName());
//            File file = FileUtil.touch(successFileName);
//
//            // 定义时间格式化器（线程安全）
//            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//
//            // 分批大小
//            long pageSize = 1000;
//
//            try (CSVWriter writer = new CSVWriter(
//                    new OutputStreamWriter(
//                            new FileOutputStream(file),
//                            java.nio.charset.StandardCharsets.UTF_8),
//                    ',',  // 分隔符
//                    CSVWriter.DEFAULT_QUOTE_CHARACTER,
//                    CSVWriter.DEFAULT_ESCAPE_CHARACTER,
//                    CSVWriter.DEFAULT_LINE_END
//            )) {
//                // 写入表头
//                writer.writeNext(headerAliasMap.values().toArray(new String[0]));
//
//                // 分批处理数据
//                long current = 1;
//                long offset = 0;
//                while (offset < totalCount) {
//                    // 获取当前批次数据
//                    IPage<ExportAwardVO> page = dataProvider.apply(new long[]{current, pageSize});
//                    List<ExportAwardVO> batchList = page.getRecords();
//
//                    // 写入当前批次数据
//                    for (ExportAwardVO item : batchList) {
//                        String[] row = headerAliasMap.keySet().stream()
//                                .map(field -> {
//                                    Object value = BeanUtil.getProperty(item, field);
//                                    // 特殊处理时间类型字段
//                                    if (value instanceof TemporalAccessor) {  // 支持LocalDateTime/Date等
//                                        return escapeCsvField(formatter.format((TemporalAccessor) value));
//                                    } else if (value instanceof Date) {
//                                        return escapeCsvField(formatter.format(((Date) value).toInstant().atZone(ZoneId.systemDefault())));
//                                    }
//                                    return escapeCsvField(Convert.toStr(value, ""));
//                                })
//                                .toArray(String[]::new);
//                        writer.writeNext(row);
//                    }
//
//                    offset += batchList.size();
//                    current++;
//
//                    // 如果当前批次数据少于pageSize，说明已经处理完所有数据
//                    if (batchList.size() < pageSize) {
//                        break;
//                    }
//                }
//
//                // 刷新缓冲区，确保数据写入磁盘
//                writer.flush();
//                // 设置文件大小
//                sysExportTaskEntity.setFileSize(file.length());
//
//                // 上传文件到OSS
//                org.springframework.mock.web.MockMultipartFile mockMultipartFile = new org.springframework.mock.web.MockMultipartFile(
//                        successFileName,
//                        successFileName,
//                        "text/csv;charset=UTF-8",
//                        new java.io.FileInputStream(file));
//                successUrl = ossFileService.singleFileUpload(mockMultipartFile, OssFileConfig.BIZ_TYPE.DOWNLOAD);
//            } catch (Exception e) {
//                throw new BizException(e.getMessage());
//            } finally {
//                FileUtil.del(file);
//            }
//        }
//        return successUrl;
//    }
//


    /**
     * CSV字段转义（RFC4180规范）
     */
    private String escapeCsvField(String field) {
        if (field == null) return "";

        boolean needQuote = field.contains(",")
                || field.contains("\"")
                || field.contains("\n")
                || field.contains("\r");

        String escaped = field.replace("\"", "\"\"");
        return needQuote ? "\"" + escaped + "\"" : escaped;
    }


    /** 获取对象类型 **/
    protected <V> V getRequestParam(String requestParamStr, Class<V> clazz) {
        V requestParam = JSONObject.parseObject(requestParamStr, clazz);
        if (ObjectUtils.isEmpty(requestParam)) {
            throw new BizException("请求参数异常");
        }
        return requestParam;
    }

    /** 获取对象类型 **/
    protected JSONObject getRequestParam(String requestParamStr) {
        JSONObject requestParam = JSONObject.parseObject(requestParamStr);
        if (ObjectUtils.isEmpty(requestParam)) {
            throw new BizException("请求参数异常");
        }
        return requestParam;
    }
}
